package net.stogi.unicore.beyond.ui.client.taskeditor.taskoutline;

import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.mvp.AbstractPresenter;
import net.stogi.common.mvp.core.behavior.Behavior;
import net.stogi.unicore.beyond.api.model.InputDefinition;
import net.stogi.unicore.beyond.api.model.InputGroup;
import net.stogi.unicore.beyond.api.model.OutputDefinition;
import net.stogi.unicore.beyond.api.model.OutputGroup;
import net.stogi.unicore.beyond.api.model.TaskDefinition;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewClosedEvent;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewClosedHandler;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewOpenedEvent;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewOpenedHandler;

class PropertyEditorPresenter extends AbstractPresenter {

	private TaskDefinition taskDefinition;

	private InputDefinition inputDefinition;

	private InputGroup inputGroup;

	private OutputDefinition outputDefinition;

	private OutputGroup outputGroup;

	private PropertyEditorView propertyEditorView;

	public PropertyEditorPresenter(PropertyEditorView propertyEditorView, ActionManager actionManager, EventBus eventBus) {
		super(actionManager, eventBus);
		this.propertyEditorView = propertyEditorView;
		initBehavior();
		initHandlers();
	}

	@Override
	protected void initBehavior() {
		propertyEditorView.setCancelBehavior(new Behavior() {

			@Override
			public void behave() {
				inputDefinition = null;
				inputGroup = null;
				outputDefinition = null;
				outputGroup = null;
				propertyEditorView.disappear();
				propertyEditorView.clear();
			}
		});
		propertyEditorView.setOkBehavior(new Behavior() {

			@Override
			public void behave() {
				String name = propertyEditorView.collectName();

				if (name != null) {
					// Name of input definition was edited.
					if (inputDefinition != null) {
						if (!name.equals(inputDefinition.getName()) && taskDefinition.containsInputDefinitionWithName(name)) {
							propertyEditorView.invalidName("Input definition with name '" + name + "' already exists");
							return;
						}
						inputDefinition.setName(name);
					}
					// Name of input group was edited.
					else if (inputGroup != null) {
						if (!name.equals(inputGroup.getName()) && taskDefinition.containsInputGroupWithName(name)) {
							propertyEditorView.invalidName("Input group with name '" + name + "' already exists");
							return;
						}
						inputGroup.setName(name);
					}
					// Name of output definition was edited.
					else if (outputDefinition != null) {
						if (!name.equals(outputDefinition.getName()) && taskDefinition.containsOutputDefinitionWithName(name)) {
							propertyEditorView.invalidName("Output definition with name '" + name + "' already exists");
							return;
						}
						outputDefinition.setName(name);
					}
					// Name of output group was edited.
					else if (outputGroup != null) {
						if (!name.equals(outputGroup.getName()) && taskDefinition.containsOutputGroupWithName(name)) {
							propertyEditorView.invalidName("Output group with name '" + name + "' already exists");
							return;
						}
						outputGroup.setName(name);
					}

					eventBus.fireEvent(new TaskDefinitionEditedEvent());
					inputDefinition = null;
					inputGroup = null;
					outputDefinition = null;
					outputGroup = null;
					propertyEditorView.disappear();
					propertyEditorView.clear();
				}
			}
		});
	}

	@Override
	protected void initHandlers() {
		// Task definition closed.
		eventBus.addHandler(TaskPreviewClosedEvent.TYPE, new TaskPreviewClosedHandler() {

			@Override
			public void onTaskPreviewClosed(TaskPreviewClosedEvent event) {
				taskDefinition = null;
			}
		});
		// Task definition opened.
		eventBus.addHandler(TaskPreviewOpenedEvent.TYPE, new TaskPreviewOpenedHandler() {

			@Override
			public void onTaskPreviewOpened(TaskPreviewOpenedEvent event) {
				taskDefinition = event.getTaskDefinition();
			}
		});
		// Edit input definition.
		eventBus.addHandler(EditInputDefinitionEvent.TYPE, new EditInputDefinitionHandler() {

			@Override
			public void onEditInputDefinition(EditInputDefinitionEvent event) {
				inputDefinition = event.getInputDefinition();
				propertyEditorView.displayName(inputDefinition.getName());
				propertyEditorView.appear();
			}
		});
		// Edit input group.
		eventBus.addHandler(EditInputGroupEvent.TYPE, new EditInputGroupHandler() {

			@Override
			public void onEditInputGroup(EditInputGroupEvent event) {
				inputGroup = event.getInputGroup();
				propertyEditorView.displayName(inputGroup.getName());
				propertyEditorView.appear();
			}
		});
		// Edit output definition.
		eventBus.addHandler(EditOutputDefinitionEvent.TYPE, new EditOutputDefinitionHandler() {

			@Override
			public void onEditOutputDefinition(EditOutputDefinitionEvent event) {
				outputDefinition = event.getOutputDefinition();
				propertyEditorView.displayName(outputDefinition.getName());
				propertyEditorView.appear();
			}
		});
		// Edit input group.
		eventBus.addHandler(EditOutputGroupEvent.TYPE, new EditOutputGroupHandler() {

			@Override
			public void onEditOutputGroup(EditOutputGroupEvent event) {
				outputGroup = event.getOutputGroup();
				propertyEditorView.displayName(outputGroup.getName());
				propertyEditorView.appear();
			}
		});
	}
}
